//Basic Raycasting code for hitscan, line checks, etc
/*
local function XYZCollide(x, y, z, mo)
	if mo.flags & MF_NOCLIP or mo.flags & MF_NOCLIPTHING then return false end
	if x > mo.x+(mo.radius/2) then return false end
	if x < mo.x-(mo.radius/2) then return false end
	if y > mo.y+(mo.radius/2) then return false end
	if y < mo.y-(mo.radius/2) then return false end
	if z > mo.height+mo.z then return false end
	if z < mo.z then return false end
	return true
end

local function ParseArg(args, variable, default)
	if not args then
		return default
	end

	if args[variable] == nil then
		return default
	end

	if default ~= nil
	and type(args[variable]) ~= type(default)then
		return default
	end

	return args[variable]
end

rawset(_G, "P_AngleRaycast", function(args)
// Arguments
	local x = ParseArg(args, "x", 0)
	local y = ParseArg(args, "y", 0)
	local z = ParseArg(args, "z", 0)
	local ang = ParseArg(args, "ang", 0)
	local zang = ParseArg(args, "zang", 0)
	local distance = ParseArg(args, "distance", 256*FU)
	local steps = ParseArg(args, "steps", 32)
	local callback = ParseArg(args, "callback")
	local callback2 = ParseArg(args, "callback2")
	local arg = ParseArg(args, "arg")
	local sarg = ParseArg(args, "sarg")
	local larg = ParseArg(args, "larg")
	local tclip = ParseArg(args, "tclip")
	local lclip = ParseArg(args, "lclip")
	local ignore = ParseArg(args, "ignore")
	local move = distance/steps
	local dummy = nil
	
	local collisionlist = {}
	local vx = FixedMul(cos(ang), cos(zang))
	local vy = FixedMul(sin(ang), cos(zang))
	local vz = sin(zang)
	
	for stepcount = 1, steps do
		x = $ + FixedMul(move, vx)
		y = $ + FixedMul(move, vy)
		z = $ + FixedMul(move, vz)
		if callback then
			callback(x, y, z, arg)
		end
		if dummy == nil or (not dummy.valid) then
			print(stepcount .. "spawn")
			dummy = P_SpawnMobj(x, y, z, MT_RAY2)
		else
			print(stepcount .. "move")
			P_SetOrigin(dummy, x, y, z)
		end
		if searchBlockmap("objects", function(ref, object)
			if object == ignore then return nil end
			if collisionlist[object] then return nil end
			if XYZCollide(x, y, z, object) then
				collisionlist[object] = {x, y, z, stepcount}
				if callback2 then
					callback2(x, y, z, sarg, object)
				end
				if tclip == true or tclip == 1 then return true
				else return nil end
			end
		end, dummy) == false then break end
		if lclip == true or lclip == 1 then
			local sect = dummy.subsector.sector
			if z < sect.floorheight or z > sect.ceilingheight then
				if callback2 then
					callback2(x-FixedMul(move, vx), y-FixedMul(move, vy), z-FixedMul(move, vz), larg or sarg)
				end
				break
			end
			if P_CheckPosition(dummy, x, y) == false then
				if callback2 then
					callback2(x-FixedMul(move, vx), y-FixedMul(move, vy), z-FixedMul(move, vz), larg or sarg)
				end
				break
			end
		end
	end
	P_RemoveMobj(dummy)
	return collisionlist
end)

COM_AddCommand("raytest", function(bruh, x, y, z, ang, zang, step, amount)
	P_AngleRaycast(tonumber(x)*FU, tonumber(y)*FU, tonumber(z)*FU, FixedAngle(tonumber(ang)*FU), FixedAngle(tonumber(zang)*FU), tonumber(step), tonumber(amount), P_SpawnMobj, nil, MT_THOK, nil, true, true)
end)